package com.inexas.cu.client.register;

import com.google.inject.*;
import com.inexas.cu.client.eventbus.*;
import com.inexas.cu.client.mvp.*;

/**
 * This must be testable but not reachable from the sign in view
 */
public class SignInPresenter implements Source {
	private final EventBus eventBus;
	private final SignInViewImpl view;
	private SignInPm signInPm;

	@Inject
	public SignInPresenter(SignInViewImpl view, EventBus eventBus) {
		this.eventBus = eventBus;
		this.view = view;
	}
	
	public void setSignInPm(SignInPm signInPm) {
		assert signInPm != null;
		assert this.signInPm == null : "Already bound, you can only call this method once";
		
		this.signInPm = signInPm;
		
		handleChange();
		
		// Bind the view...
		view.bind(signInPm);
		
		// Now bind ourselves...
		signInPm.addObserver(new Observer() {
			public void onChanged(Source source, Notification notification) {
				handleChange();
			}
		});
		signInPm.getSignInActuator().addObserver(new Observer() {
			public void onChanged(Source source, Notification notification) {
				doSignIn();
			}
			
		});
	}

    private void handleChange() {
		final boolean enabled = getAccountName() != null && getPassword() != null;
		signInPm.getSignInActuator().setAccess(enabled ? Property.Access.READWRITE : Property.Access.READONLY);
	}

	private String getAccountName() {
		return normalize(signInPm.getAccountName());
	}

	private String getPassword() {
		return normalize(signInPm.getPassword());
	}

	private String normalize(Property<String> property) {
		final String result;
		String value = property.getValue();
		if(value == null) {
			result = null;
		} else {
			final String trimmed = value.trim();
			result = trimmed.length() == 0 ? null : trimmed;
		}
		return result;
	}

	private void doSignIn() {
		final SignIn signIn = new SignIn(getAccountName(), getPassword());
		eventBus.fireEvent(signIn);
	}

}